const net = require('net');
const fs = require('fs').promises;
const path = require('path');
const ipp = require('ipp');
const { Document } = require('../models/document');
const { Printer } = require('../models/printer');
const docxConverter = require('docx-pdf');
const pdf = require('pdf-poppler');
const sharp = require('sharp');
const { promisify } = require('util');
const { existsSync } = require('fs');
const axios = require('axios');
const https = require('https');

// 将 docx-pdf 转换函数转换为 Promise
const convertDocxToPdf = promisify(docxConverter);

// 将 PDF 转换为 URF 格式
async function convertToPWG(pdfPath) {
    console.log('开始将 PDF 转换为 URF 格式');

    try {
        // 确保临时目录存在
        const tempDir = path.join(process.cwd(), 'temp');
        await fs.mkdir(tempDir, { recursive: true });
        console.log('临时目录已创建:', tempDir);

        // 设置输出选项
        const outputFile = path.join(tempDir, 'output');
        const opts = {
            format: 'png',
            out_dir: tempDir,
            out_prefix: 'output',
            page: 1,
            scale: 4.0, // 600dpi
        };

        console.log('PDF 转换选项:', opts);

        // 转换 PDF 到 PNG
        console.log('转换第一页...');
        await pdf.convert(pdfPath, opts);

        // 读取生成的 PNG 文件
        const pngPath = path.join(tempDir, 'output-1.png');
        console.log('检查生成的 PNG 文件:', pngPath);

        if (!existsSync(pngPath)) {
            throw new Error('PDF 转换失败：未能生成图像文件');
        }

        // 使用 sharp 处理图像
        console.log('处理图像...');
        const image = await sharp(pngPath)
            .resize(4960, 7016) // A4 尺寸 @ 600dpi
            .grayscale() // 转换为灰度图像
            .png({ quality: 75, compressionLevel: 9 }) // 使用 PNG 压缩
            .toBuffer();

        // URF 头部 (32字节)
        const urfHeader = Buffer.alloc(32);
        urfHeader.write('UNIRAST', 0);  // URF 魔数
        urfHeader.writeUInt32BE(1, 8);  // 版本号
        urfHeader.writeUInt32BE(4960, 12); // 页面宽度
        urfHeader.writeUInt32BE(7016, 16); // 页面高度
        urfHeader.writeUInt32BE(600, 20);  // DPI
        urfHeader.writeUInt8(8, 24);      // BPC (bits per component)
        urfHeader.writeUInt8(1, 25);      // ColorSpace (1 = DeviceGray)
        urfHeader.writeUInt8(1, 26);      // Duplex
        urfHeader.writeUInt8(0, 27);      // 质量

        // 合并头部和图像数据
        const urfData = Buffer.concat([urfHeader, image]);

        // 清理临时文件
        try {
            await fs.unlink(pngPath);
            console.log('临时 PNG 文件已删除');
        } catch (error) {
            console.warn('删除临时 PNG 文件失败:', error);
        }

        console.log('URF 数据生成完成，大小:', urfData.length, '字节');
        return urfData;
    } catch (error) {
        console.error('转换为 URF 格式失败:', error);
        // 尝试清理临时文件
        try {
            const tempDir = path.join(process.cwd(), 'temp');
            if (existsSync(tempDir)) {
                await fs.rm(tempDir, { recursive: true, force: true });
                console.log('临时目录已清理');
            }
        } catch (cleanupError) {
            console.error('清理临时目录失败:', cleanupError);
        }
        throw error;
    }
}

class PrintService {
    constructor() {
        this.tempDir = path.join(process.cwd(), 'temp');
        if (!existsSync(this.tempDir)) {
            fs.mkdir(this.tempDir, { recursive: true });
        }
    }

    static async printDocument(taskId) {
        let task = null;
        let printer = null;
        let tempPdfPath = null;

        try {
            // 获取任务信息
            task = await Document.findByPk(taskId);
            if (!task) {
                throw new Error('打印任务不存在');
            }

            // 获取打印机信息
            printer = await Printer.findByPk(task.printerId);
            if (!printer) {
                throw new Error('打印机不存在');
            }

            console.log(`开始处理打印任务: ${taskId}`);
            console.log(`文件路径: ${task.path}`);
            console.log(`打印机信息: IP=${printer.ip}, 端口=${printer.port}, 协议=${printer.protocol}`);

            // 首先检查打印机状态
            const printerStatus = await this.checkPrinterStatus(printer.ip, printer.port);
            if (!printerStatus.isReady) {
                throw new Error(`打印机不可用: ${printerStatus.message}`);
            }

            // 准备打印数据
            let printData;
            const fileExt = path.extname(task.path).toLowerCase();

            // 确保临时目录存在
            const tempDir = path.join(process.cwd(), 'temp');
            await fs.mkdir(tempDir, { recursive: true });
            console.log('临时目录已创建:', tempDir);

            if (fileExt === '.docx') {
                console.log('转换 Word 文档为 PDF');
                // 设置临时 PDF 文件路径
                tempPdfPath = path.join(tempDir, `${path.basename(task.path, '.docx')}.pdf`);

                try {
                    // 转换文档
                    await convertDocxToPdf(task.path, tempPdfPath);
                    console.log('文档转换完成，转换为 URF 格式');

                    // 转换为 URF 格式
                    printData = await convertToPWG(tempPdfPath);
                } catch (error) {
                    console.error('文档转换失败:', error);
                    throw new Error('文档转换失败: ' + error.message);
                }
            } else if (fileExt === '.pdf') {
                // 如果是 PDF，直接转换为 URF 格式
                printData = await convertToPWG(task.path);
            } else {
                throw new Error('不支持的文件格式: ' + fileExt);
            }

            // 直接使用 IPP 协议打印
            console.log('使用IPP协议打印...');
            await this.printWithIPP(printer.ip, printer.port, task, printData);

            // 更新任务状态为已完成
            await task.update({ status: 'completed' });
            console.log('打印任务完成');

            return true;
        } catch (error) {
            console.error('打印执行失败:', error);

            // 更新任务状态为失败
            if (task) {
                await task.update({
                    status: 'failed',
                    errorMessage: error.message
                });
                console.log('更新任务状态为失败');

                // 更新打印机失败计数
                if (printer) {
                    await printer.increment('failedPrintCount');
                    console.log('更新打印机失败计数');
                }
            }
            throw error;
        } finally {
            // 清理临时文件
            try {
                if (tempPdfPath && existsSync(tempPdfPath)) {
                    await fs.unlink(tempPdfPath);
                    console.log('临时 PDF 文件已删除');
                }

                const tempDir = path.join(process.cwd(), 'temp');
                if (existsSync(tempDir)) {
                    await fs.rm(tempDir, { recursive: true, force: true });
                    console.log('临时目录已清理');
                }
            } catch (error) {
                console.error('清理临时文件失败:', error);
            }
        }
    }

    static async printWithIPP(ip, port, task, printData) {
        return new Promise((resolve, reject) => {
            console.log('\n=== 开始IPP打印 ===');
            const printerUrl = `ipp://${ip}:${port}/ipp/print`;
            console.log('打印机URL:', printerUrl);

            const printer = ipp.Printer(printerUrl, {
                version: '1.1',
                uri: printerUrl
            });

            const msg = {
                "operation-attributes-tag": {
                    "requesting-user-name": "OEasy Printer",
                    "job-name": task.originalName,
                    "document-format": "image/urf",
                    "ipp-attribute-fidelity": true
                },
                "job-attributes-tag": {
                    "copies": 1,
                    "media": "iso_a4_210x297mm",
                    "orientation-requested": "portrait",
                    "print-quality": "normal",
                    "printer-resolution": [600, 600, "dpi"],
                    "print-color-mode": "monochrome",
                    "sides": "one-sided"
                },
                data: printData
            };

            console.log('\n打印任务参数:');
            console.log('文档名称:', task.originalName);
            console.log('文档格式: image/urf');
            console.log('分辨率: 600x600 dpi');
            console.log('颜色模式: monochrome');
            console.log('纸张: A4');
            console.log('打印质量: normal');
            console.log('打印面: one-sided');
            console.log('数据大小:', printData.length, '字节\n');

            const maxRetries = 3;
            let retryCount = 0;

            const tryPrint = () => {
                console.log(`尝试打印 (第 ${retryCount + 1} 次)`);
                printer.execute("Print-Job", msg, (err, res) => {
                    if (err) {
                        console.error(`第 ${retryCount + 1} 次尝试失败:`, err.message);

                        if (retryCount < maxRetries - 1) {
                            retryCount++;
                            setTimeout(tryPrint, 5000);
                            return;
                        }

                        reject(new Error(`打印失败，已重试 ${maxRetries} 次: ${err.message}`));
                        return;
                    }

                    console.log('IPP打印响应:', JSON.stringify(res, null, 2));

                    if (res.statusCode === 'successful-ok') {
                        const jobId = res['job-attributes-tag'] ? res['job-attributes-tag']['job-id'] : null;
                        if (jobId) {
                            console.log('打印任务ID:', jobId);
                        }
                        console.log('打印任务已成功发送到打印机');
                        resolve();
                    } else {
                        if (retryCount < maxRetries - 1) {
                            retryCount++;
                            setTimeout(tryPrint, 5000);
                            return;
                        }

                        reject(new Error(`打印失败: ${res.statusCode}`));
                    }
                });
            };

            tryPrint();
        });
    }

    static getDocumentFormat(filePath) {
        const ext = path.extname(filePath).toLowerCase();
        const formatMap = {
            '.pdf': 'application/pdf',
            '.txt': 'text/plain',
            '.doc': 'application/msword',
            '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
            '.xls': 'application/vnd.ms-excel',
            '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
        };
        return formatMap[ext] || 'application/octet-stream';
    }

    static async checkPrinterStatus(ip, port) {
        return new Promise((resolve, reject) => {
            console.log('\n=== 开始检查打印机状态 ===');
            const printerUrl = `ipp://${ip}:${port}/ipp/print`;
            const printer = ipp.Printer(printerUrl);

            printer.execute("Get-Printer-Attributes", {
                "operation-attributes-tag": {
                    "requesting-user-name": "OEasy Printer",
                    "requested-attributes": [
                        "printer-make-and-model",
                        "printer-state",
                        "printer-state-reasons",
                        "printer-state-message",
                        "document-format-supported",
                        "printer-resolution-supported",
                        "print-color-mode-supported",
                        "printer-is-accepting-jobs",
                        "printer-up-time",
                        "queued-job-count",
                        "printer-current-time",
                        "compression-supported",
                        "media-supported",
                        "sides-supported"
                    ]
                }
            }, (err, res) => {
                if (err) {
                    console.error('获取打印机属性失败:', err);
                    resolve({
                        isReady: false,
                        message: `无法获取打印机状态: ${err.message}`
                    });
                    return;
                }

                const attrs = res['printer-attributes-tag'];

                console.log('\n=== 打印机基本信息 ===');
                console.log('型号:', attrs['printer-make-and-model']);
                console.log('当前时间:', attrs['printer-current-time']);
                console.log('运行时间:', attrs['printer-up-time'], '秒');
                console.log('队列中的任务数:', attrs['queued-job-count']);

                console.log('\n=== 打印机状态 ===');
                const stateMap = {
                    '3': '空闲',
                    '4': '处理中',
                    '5': '停止'
                };
                console.log('状态:', stateMap[attrs['printer-state']] || attrs['printer-state']);
                console.log('状态原因:', attrs['printer-state-reasons']);
                console.log('状态消息:', attrs['printer-state-message']);
                console.log('是否接受任务:', attrs['printer-is-accepting-jobs']);

                console.log('\n=== 打印机能力 ===');
                console.log('支持的格式:', attrs['document-format-supported']);
                console.log('支持的分辨率:', attrs['printer-resolution-supported']);
                console.log('支持的颜色模式:', attrs['print-color-mode-supported']);
                console.log('支持的压缩方式:', attrs['compression-supported']);
                console.log('支持的纸张:', attrs['media-supported']);
                console.log('支持的打印面:', attrs['sides-supported']);
                console.log('\n=== 打印机检查完成 ===\n');

                // 检查打印机是否可用
                const state = attrs['printer-state'];
                const isAcceptingJobs = attrs['printer-is-accepting-jobs'];
                const stateReasons = attrs['printer-state-reasons'];

                let isReady = true;
                let message = '打印机就绪';

                if (state === 5) {
                    isReady = false;
                    message = '打印机已停止';
                } else if (!isAcceptingJobs) {
                    isReady = false;
                    message = '打印机不接受任务';
                } else if (stateReasons && stateReasons !== 'none') {
                    if (stateReasons.includes('media-empty')) {
                        isReady = false;
                        message = '打印机缺纸';
                    } else if (stateReasons.includes('toner-low')) {
                        console.warn('警告: 墨粉不足');
                    }
                }

                // 检查是否支持所需的格式和分辨率
                const supportedFormats = attrs['document-format-supported'] || [];
                if (!supportedFormats.includes('image/urf')) {
                    isReady = false;
                    message = '打印机不支持 URF 格式';
                }

                resolve({
                    isReady,
                    message,
                    attributes: attrs
                });
            });
        });
    }
}

module.exports = PrintDemo;